package com.member.web.job;

import com.alibaba.fastjson2.JSON;
import com.alibaba.fastjson2.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.member.common.utils.fy.HttpUtil;
import com.member.common.utils.fy.SignatureUtils;
import com.member.shop.domain.SysBizOrder;
import com.member.shop.domain.SysBizOrderGoods;
import com.member.shop.domain.SysBizShopCertification;
import com.member.shop.dto.ReceiveHyOrderDto;
import com.member.shop.dto.ReceiveHyProductsDto;
import com.member.shop.mapper.SysBizOrderMapper;
import com.member.shop.mapper.SysBizShopCertificationMapper;
import com.member.shop.service.ISysBizOrderGoodsService;
import com.member.shop.service.ISysBizOrderService;
import lombok.extern.log4j.Log4j2;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;
import org.springframework.util.CollectionUtils;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.TimeUnit;

/**
 * @author luo.yun
 * @Description OrderSendJob 订单推送定时任务
 * @ClassName OrderSendJob
 * @Date 2025/3/18
 */
@Component
@Log4j2
public class OrderSendJob {

    @Resource
    private ISysBizOrderService sysBizOrderService;

    @Resource
    private SysBizOrderMapper sysBizOrderMapper;

    @Resource
    private ISysBizOrderGoodsService sysBizOrderGoodsService;

    @Value("${mall.order.pushUrl}")
    private String url;


    @Value("${mall.order.privateKey}")
    private String privateKey;

    @Autowired
    public RedisTemplate redisTemplate;


    @Resource
    private SysBizShopCertificationMapper sysBizShopCertificationMapper;

    @Scheduled(cron = "0 0/5 * * * ?")
    public void orderSendJob() {

        String lockKey = "order_lock_push";

        //redission 后面再加上看门狗
        // 循环尝试获取锁
        while (true) {
            Boolean lockAcquired = redisTemplate.opsForValue().setIfAbsent(lockKey, "locked", 10, TimeUnit.SECONDS); // 设置 10 秒超时锁

            if (Boolean.TRUE.equals(lockAcquired)) {
                log.info("成功获取锁，开始处理订单...");
                break; // 成功获取锁后退出循环
            }

            log.info("未能获取锁，等待 1 秒后重试...");
            try {
                Thread.sleep(1000); // 等待 1 秒后重试
            } catch (InterruptedException e) {
                Thread.currentThread().interrupt(); // 恢复线程中断状态
                log.error("线程被中断，任务退出");
                return;
            }
        }

        try {
            List<SysBizOrder> sysBizOrders = sysBizOrderService.selectSysBizOrderList(
                    new LambdaQueryWrapper<SysBizOrder>().eq(SysBizOrder::getStatus, 15)
                            .lt(SysBizOrder::getPushNum, 3)
                            .eq(SysBizOrder::getDelStatus, 0)
            );
            if (CollectionUtils.isEmpty(sysBizOrders)) {
                return;
            }
            for (SysBizOrder sysBizOrder : sysBizOrders) {
                log.info("定时任务id:{}",sysBizOrder.getId());
                SysBizOrder sysBizOrder1 = sysBizOrderService.selectSysBizOrderById(sysBizOrder.getId());
                if (sysBizOrder1.getStatus() != 15) {
                    log.info("定时状态修改:{}",sysBizOrder.getId());
                    continue;
                }
                log.info("定时任务id2:{}",sysBizOrder.getId());
                sysBizOrder.setReceiverAddress(sysBizOrder.getProvince() + sysBizOrder.getCity() + sysBizOrder.getArea() + sysBizOrder.getStreet() + sysBizOrder.getHouseNum());
                SysBizOrderGoods sysBizOrderGoods = new SysBizOrderGoods();
                sysBizOrderGoods.setOrderId(sysBizOrder.getId());
                List<SysBizOrderGoods> sysBizOrderGoodsList = sysBizOrderGoodsService.selectSysBizOrderGoodsList(sysBizOrderGoods);
                if (sysBizOrderGoodsList != null) {
                    for (SysBizOrderGoods bizOrderGoods : sysBizOrderGoodsList) {
                        bizOrderGoods.setSpecsName(bizOrderGoods.getSpecsKey());
                    }
                }
                sysBizOrder.setSysBizOrderGoodsList(sysBizOrderGoodsList);


                ReceiveHyOrderDto receiveHyOrderDto = new ReceiveHyOrderDto();
                receiveHyOrderDto.setId(sysBizOrder.getId()); // 订单id
                receiveHyOrderDto.setOrderCode(sysBizOrder.getOrderCode());// 订单编号
                receiveHyOrderDto.setStatus(sysBizOrder.getStatus());  // 订单状态
                receiveHyOrderDto.setUserId(sysBizOrder.getUserId());  // 下单人id
                //        receiveHyOrderDto.setBelongShopId(sysBizOrder.getBelongShopId());  // 归属店铺id
                //        receiveHyOrderDto.setBelongDealerId(sysBizOrder.getBelongDealerId()); // 归属经销商id


                receiveHyOrderDto.setBelongShopId(0L);  // 先传0
                receiveHyOrderDto.setBelongDealerId(0L); // 先传0

                //传店铺名称
                List<SysBizShopCertification> sysBizShopCertifications = sysBizShopCertificationMapper.selectList(
                        new LambdaQueryWrapper<SysBizShopCertification>()
                                .eq(SysBizShopCertification::getUserId, sysBizOrder.getUserId())
                                .eq(SysBizShopCertification::getTenantId, sysBizOrder.getTenantId())
                                .eq(SysBizShopCertification::getDeleted, 0)
                                .eq(SysBizShopCertification::getCertificationStatus, 3)
                                .last("limit 1")
                );
                if (!CollectionUtils.isEmpty(sysBizShopCertifications)) {
                    receiveHyOrderDto.setUserName(sysBizShopCertifications.get(0).getShopName());
                } else {
                    receiveHyOrderDto.setUserName(sysBizOrder.getUserName()); // 下单人
                }

                receiveHyOrderDto.setTenantId(sysBizOrder.getTenantId()); //站点Id
                receiveHyOrderDto.setPhone(sysBizOrder.getPhone());// 下单人手机号
                receiveHyOrderDto.setAmount(sysBizOrder.getAmount());// 订单金额
                receiveHyOrderDto.setPayableAmount(sysBizOrder.getPayableAmount());// 应付金额
                receiveHyOrderDto.setActualPaymentAmount(sysBizOrder.getActualPaymentAmount());// 实付金额
                receiveHyOrderDto.setTotalPrice(sysBizOrder.getTotalPrice());// 总计
                receiveHyOrderDto.setPaymentStatus(sysBizOrder.getPaymentStatus());// 支付状态
                receiveHyOrderDto.setPaymentNo(sysBizOrder.getPaymentNo());// 支付流水号
                receiveHyOrderDto.setPaymentTime(sysBizOrder.getPaymentTime()); // 支付时间
                receiveHyOrderDto.setAddressId(sysBizOrder.getAddressId());
                receiveHyOrderDto.setReceiver(sysBizOrder.getReceiver()); // 收货人
                receiveHyOrderDto.setContactNumber(sysBizOrder.getContactNumber()); // 收货人联系电话
                receiveHyOrderDto.setReceiverAddress(sysBizOrder.getReceiverAddress()); // 收货地址
                receiveHyOrderDto.setOrderAddTime(sysBizOrder.getOrderAddTime()); // 下单时间
                receiveHyOrderDto.setProvince(sysBizOrder.getProvince()); // 省
                receiveHyOrderDto.setCity(sysBizOrder.getCity()); // 市
                receiveHyOrderDto.setArea(sysBizOrder.getArea()); // 区
                receiveHyOrderDto.setStreet(sysBizOrder.getStreet()); // 街道 (街道数据需统一，平台端后续会提供）)
                receiveHyOrderDto.setLongitude(sysBizOrder.getLng()); // 收货地址经度
                receiveHyOrderDto.setLatitude(sysBizOrder.getLat()); // 收货地址纬度
                receiveHyOrderDto.setRemark(sysBizOrder.getRemark()); // 备注
                receiveHyOrderDto.setCouponPrice(sysBizOrder.getCouponPrice()); // 优惠券金额
                receiveHyOrderDto.setTransactionId(sysBizOrder.getTransactionId()); // 微信流水号

                List<ReceiveHyProductsDto> receiveHyProductsDtos = new ArrayList<ReceiveHyProductsDto>();
                if (!CollectionUtils.isEmpty(sysBizOrder.getSysBizOrderGoodsList())) {
                    for (SysBizOrderGoods bizOrderGoods : sysBizOrder.getSysBizOrderGoodsList()) {
                        ReceiveHyProductsDto receiveHyProductsDto = new ReceiveHyProductsDto();
                        receiveHyProductsDto.setId(bizOrderGoods.getId());
                        receiveHyProductsDto.setOrderId(String.valueOf(bizOrderGoods.getOrderId()));
                        receiveHyProductsDto.setGoodsId(bizOrderGoods.getGoodsId());
                        receiveHyProductsDto.setProductCode(bizOrderGoods.getErpProductCode());
//                        receiveHyProductsDto.setLongUnitNumber(bizOrderGoods.getLongUnitNumber());
                        receiveHyProductsDto.setGoodsName(bizOrderGoods.getGoodsName());
                        receiveHyProductsDto.setUnitPrice(bizOrderGoods.getUnitPrice());
                        receiveHyProductsDto.setTotalPrice(bizOrderGoods.getTotalPrice());
//                        receiveHyProductsDto.setNumber(Integer.parseInt(String.valueOf(bizOrderGoods.getNumber())) * bizOrderGoods.getLongUnitNumber());
//                        receiveHyProductsDto.setNumber(Integer.parseInt(String.valueOf(bizOrderGoods.getNumber())));
                        if(bizOrderGoods.getErpSmallUnit()==1){
                            receiveHyProductsDto.setNumber(Integer.parseInt(String.valueOf(bizOrderGoods.getNumber())) * bizOrderGoods.getLongUnitNumber());
                        }else{
                            receiveHyProductsDto.setNumber(Integer.parseInt(String.valueOf(bizOrderGoods.getNumber())));
                        }
                        receiveHyProductsDtos.add(receiveHyProductsDto);
                    }

                }
                receiveHyOrderDto.setProducts(receiveHyProductsDtos); // 订单商品集合

                try {
                    // 订单信息

                    // 时间戳
                    String timeStamp = String.valueOf(System.currentTimeMillis());

                    // 签名（假设使用 SHA-256 对 data 和 timeStamp 进行签名）
                    String sign = SignatureUtils.signWithSHA1(JSON.toJSONString(receiveHyOrderDto), SignatureUtils.getPrivateKey(privateKey));

                    // 请求体
                    Map<String, Object> requestBody = new HashMap<>();
                    requestBody.put("timeStamp", timeStamp);
                    requestBody.put("sign", sign);
                    requestBody.put("data", JSON.toJSONString(receiveHyOrderDto));
                    log.info("请求体:{}", JSON.toJSONString(receiveHyOrderDto));

                    // 发送 POST 请求
                    String response = HttpUtil.postJson(url, JSON.toJSONString(requestBody));
                    log.info("订单推送------------:{}", response);
                    // 解析响应
                    JSONObject jsonResponse = JSON.parseObject(response);
                    int code = jsonResponse.getIntValue("code");

                    log.info("返回值------------:{}", jsonResponse);
                    // 检查 code 字段
                    if (code == 200) {
                        sysBizOrder.setStatus(20);
                        sysBizOrderMapper.updateSysBizOrder(sysBizOrder);
                    } else {
                        LambdaUpdateWrapper<SysBizOrder> updateWrapper = new LambdaUpdateWrapper<>();
                        updateWrapper.eq(SysBizOrder::getId, sysBizOrder.getId())
                                .setSql("push_num = push_num + 1");
                        sysBizOrderMapper.update(null, updateWrapper);
                    }

                } catch (Exception e) {
                    LambdaUpdateWrapper<SysBizOrder> updateWrapper = new LambdaUpdateWrapper<>();
                    updateWrapper.eq(SysBizOrder::getId, sysBizOrder.getId())
                            .setSql("push_num = push_num + 1");
                    sysBizOrderMapper.update(null, updateWrapper);
                    e.printStackTrace();
                }
            }
        } finally {
            redisTemplate.delete(lockKey); // 确保锁释放
            log.info("锁已释放");
        }

    }
}
